package testdomainexample;

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import testconditionsAPI.StubSimpleDomainCondition;
import conditionsAPI.AndDomainCondition;
import conditionsAPI.ConditionDuplicatedException;
import conditionsAPI.ConditionsConfiguration;
import conditionsAPI.NotDomainCondition;
import conditionsAPI.SimpleDomainCondition;

public class TestDomainLetters {

	private SimpleDomainCondition conditionA;
	private SimpleDomainCondition conditionB;
	private SimpleDomainCondition conditionC;
	private SimpleDomainCondition conditionE;
	private SimpleDomainCondition conditionF;
	private SimpleDomainCondition conditionI;
	private SimpleDomainCondition conditionX;
	
	private NotDomainCondition conditionNotF;
	
	private AndDomainCondition conditionD;
	private AndDomainCondition conditionG;
	private AndDomainCondition conditionH;
	
	@Before
	public void setUp(){
		try {
			
			this.conditionA = new StubSimpleDomainCondition("A");
			this.conditionB = new StubSimpleDomainCondition("B");
			this.conditionC = new StubSimpleDomainCondition("C");
			this.conditionE = new StubSimpleDomainCondition("E");
			this.conditionF = new StubSimpleDomainCondition("F");
			this.conditionI = new StubSimpleDomainCondition("I");
			this.conditionX = new StubSimpleDomainCondition("X");
			
			this.conditionNotF = new NotDomainCondition(this.conditionF);
			
			this.conditionD = new AndDomainCondition("D");
			this.conditionG = new AndDomainCondition("G");
			this.conditionH = new AndDomainCondition("H");

		} catch (ConditionDuplicatedException e) {
			e.printStackTrace();
		}
		this.createConditionsTree();
	}
	
	private void createConditionsTree(){
		this.conditionD.addPreCondition(this.conditionA);
		this.conditionD.addPreCondition(this.conditionB);
		this.conditionD.addPreCondition(this.conditionC);
		
		this.conditionG.addPreCondition(this.conditionD);
		this.conditionG.addPreCondition(this.conditionE);
		this.conditionG.addPreCondition(this.conditionNotF);
		
		this.conditionH.addPreCondition(this.conditionD);
		this.conditionH.addPreCondition(this.conditionE);
		this.conditionH.addPreCondition(this.conditionF);
		
		this.conditionNotF.addPreCondition(this.conditionI);
	}
	
	@After
	public void tearDown(){
		ConditionsConfiguration.reset();
	}
	
	@Test
	public void setTargetHAddConditionACheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABCheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXCheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXFCheckTargetResultEqualsF(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		
		//targetResult es F porque F es una precondicion de H
		assertEquals(this.conditionF.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXFCCheckTargetResultEqualsD(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		
		//targetResult es D porque D es una precondicion de H
		assertEquals(this.conditionD.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXFCXCheckTargetResultEqualsD(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		
		assertEquals(this.conditionD.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXFCXECheckTargetResultEqualsH(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionE);
		
		assertEquals(this.conditionH.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXFCXEICheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionE);
		ConditionsConfiguration.processObject(this.conditionI);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetHAddConditionsABXFCXEIFCheckTargetResultEqualsH(){
		ConditionsConfiguration.setTarget(this.conditionH);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionE);
		ConditionsConfiguration.processObject(this.conditionI);
		ConditionsConfiguration.processObject(this.conditionF);
		
		assertEquals(this.conditionH.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsACheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABCheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionABXCheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABXFCheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABXFCCheckTargetResultEqualsD(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		
		assertEquals(this.conditionD.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABXFCXCheckTargetResultEqualsD(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		
		assertEquals(this.conditionD.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABXFCXECheckTargetResultEqualsE(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionE);
		
		//targetResult es E porque es precondicion de G
		assertEquals(this.conditionE.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABXFCXEICheckTargetResultEqualsG(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionE);
		ConditionsConfiguration.processObject(this.conditionI);
		
		assertEquals(this.conditionG.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetGAddConditionsABXFCXEIFCheckTargetResultEmpty(){
		ConditionsConfiguration.setTarget(this.conditionG);
		
		ConditionsConfiguration.processObject(this.conditionA);
		ConditionsConfiguration.processObject(this.conditionB);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionF);
		ConditionsConfiguration.processObject(this.conditionC);
		ConditionsConfiguration.processObject(this.conditionX);
		ConditionsConfiguration.processObject(this.conditionE);
		ConditionsConfiguration.processObject(this.conditionI);
		ConditionsConfiguration.processObject(this.conditionF);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
}
